<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
  <title>Demo</title>
  <style>
    *{      
      -webkit-touch-callout: auto; /* prevent callout to copy image, etc when tap to hold */      
      -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */      
      -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */       
      -webkit-user-select:none;
    }  
    html,body {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
      max-width: 500px;
    }
    #block {
      position: absolute;
      left: 100px;
      top: 100px;
      width: 100px;
      height: 50px;
      overflow: hidden;
      background: red;
      color: white;
      text-align: center;
      line-height: 50px;
    }
  </style>
</head>
<body>
  <button id="start">开始</button>
  <button id="pause">暂停</button>
  <button id="play">继续</button>
  <button id="finish">结束</button>
  <button id="cancel">取消</button>
  <button id="x1">正常</button>
  <button id="x2">2倍</button>
  <button id="x4">4倍</button>
  <button id="reverse">-1倍</button>
  <div id="block">idle</div>
  <script src="/js/sprite-animator.js"></script>
  <script>

    const colorMap = {}
    function parseColor(colorStr) {
      if(typeof colorStr === 'string') {
        if(colorMap[colorStr]){
          return colorMap[colorStr]
        }

        const canvas = document.createElement('canvas'),
          context = canvas.getContext('2d')

        context.fillStyle = colorStr
        context.fillRect(0, 0, 1, 1)
        const data = context.getImageData(0, 0, 1, 1).data

        colorMap[colorStr] = {
          red: data[0],
          green: data[1],
          blue: data[2],
          alpha: data[3] / 255,
        }
        return colorMap[colorStr]
      }
      return colorStr
    }

    const animation = new SpriteAnimator.Animator(
        {width: '100px', backgroundColor: 'grey'},
        [
         {width: '50px', backgroundColor: 'grey'},
         {width: '180px', offset: 0.7, backgroundColor: '#737'},
         {width: '200px', backgroundColor: '#373'}
        ], 
        {
          duration:2000, 
          delay: 1000, 
          endDelay: 2000,
          fill: 'both',
          //iterations: 2.5,
          //iterations: Infinity,
          //direction: 'reverse',
          //direction: 'alternate-reverse',
          //playbackRate: 0.5,
          //easing: 'steps(1, end)',
          easing: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
          //easing: 'ease-in',
          // easing: {
          //   type: 'cubic-bezier',
          //   value: [0.68, -0.55, 0.265, 1.55],
          // },
        })

    animation.applyEffects({
      width: function(from, to, p, start, end){
        //console.log(from, to, p, start, end)
        from  = parseInt(from)
        to = parseInt(to)

        const dp = (p - start) / (end - start)

        return Math.round(from + (to - from) * dp) + 'px'
      },
      backgroundColor: function(from, to, p, start, end){
        from = parseColor(from)
        to = parseColor(to)

        const dp = (p - start) / (end - start)

        const r = Math.round(from.red + (to.red - from.red) * dp)
        const g = Math.round(from.green + (to.green - from.green) * dp)
        const b = Math.round(from.blue + (to.blue - from.blue) * dp)
        const a = Math.round(from.alpha + (to.alpha - from.alpha) * dp)

        return `rgba(${r},${g},${b},${a})`
      }
    })

    let requestID;

    start.onclick = function(){
      if(requestID){
        cancelAnimationFrame(requestID)
      }
      animation.cancel()
      animation.playbackRate = 1.0
      requestID = requestAnimationFrame(async function update(){
        const frame = animation.frame

        if(frame){
          block.style.width = frame.width
          block.style.backgroundColor = frame.backgroundColor
        }

        await animation.ready
        //console.log(frame, animation.playState)

        if(animation.playState === 'pending'){
          block.innerHTML = 'pending'
          // await animation.finished
          const frame = animation.frame
          block.style.width = frame.width
          block.style.backgroundColor = frame.backgroundColor          
        }

        if(animation.playState !== 'finished' && animation.playState !== 'idle') {
          requestID = requestAnimationFrame(update)
        }
      })

      block.style.backgroundColor = 'black'
      block.innerHTML = animation.playState

      console.log('start')
      animation.ready.then(() => {
        block.style.backgroundColor = 'green'
      })

      animation.finished.then(() => {
        block.style.backgroundColor = '#37c'
        block.innerHTML = animation.playState
        console.log('finished!')
      })

      animation.play()
      block.innerHTML = animation.playState

      animation.ready.then(() => {
        console.log('ready!', animation.playState)
        block.innerHTML = animation.playState
      })
    }

    pause.onclick = function(){
      animation.pause()
      block.innerHTML = animation.playState
    }

    play.onclick = function(){
      animation.play()
      block.innerHTML = animation.playState
      animation.ready.then(() => {
        console.log('resumed！')
      })
    }

    cancel.onclick = function(){
      animation.cancel()
      block.style.backgroundColor = ''
      block.style.width = animation.frame.width + 'px'
    }

    finish.onclick = function(){
      animation.finish()
    }

    x1.onclick = function(){
      animation.playbackRate = 1.0
    }
    x2.onclick = function(){
      animation.playbackRate = 2.0
    }
    x4.onclick = function(){
      animation.playbackRate = 4.0
    }
    reverse.onclick = function(){
      // animation.playbackRate = -1
      animation.reverse()
    }
  </script>
</body>
</html>